---
title: SAIF.Services.Printing business rules
summary: Enumerated business rules with per-rule trigger, enforcement, and outcomes.
status: draft
owner: SAIF Documentation
last_reviewed: 2026-08-21
library: SAIF.Services.Printing
reference_type: embedded
---

# SAIF.Services.Printing business rules

This page captures business rules enforced by `SAIF.Services.Printing`.

## BR-PRT-001 Package name extension normalization

| Field | Value |
| --- | --- |
| **Statement** | A package name ending in `.pkg` is stored without the extension. |
| **Trigger** | Any assignment to `Package` (including via `previewPDF`, `previewDocument`, `distributeDocument`) |
| **Enforcement** | `SAIF.Services.Printing/clsPrint.vb` — `Package` setter |
| **Outcome** | xPression receives the bare package name it expects |
| **Source** | SAIF.Services.Printing/clsPrint.vb |

---

## BR-PRT-002 Environment label derivation

| Field | Value |
| --- | --- |
| **Statement** | The print environment label is `Prod` when the environment service reports production, otherwise `Dev`. |
| **Trigger** | `clsPrint` construction |
| **Enforcement** | `SAIF.Services.Printing/clsPrint.vb` — `New(envSvc)` |
| **Outcome** | `Environment` exposes a two-valued environment label to callers |
| **Source** | SAIF.Services.Printing/clsPrint.vb |

---

## BR-PRT-003 Synchronous versus queued distribution

| Field | Value |
| --- | --- |
| **Statement** | Distribution is queued through MSMQ when `Asynchronous` is true, and sent directly to the xPression service otherwise. |
| **Trigger** | `distributeDocument` |
| **Enforcement** | `SAIF.Services.Printing/clsPrint.vb` — private `distributeDocument` |
| **Outcome** | Caller is decoupled from the print service when asynchronous |
| **Source** | SAIF.Services.Printing/clsPrint.vb |

---

## BR-PRT-004 Transactional MSMQ send

| Field | Value |
| --- | --- |
| **Statement** | Every MSMQ send occurs inside a transaction; if the caller did not start one, a transaction is started and committed for that single message. |
| **Trigger** | Asynchronous `distributeDocument` |
| **Enforcement** | `SAIF.Services.Printing/clsPrint.vb` — private `distributeDocument`, `StartMQTransaction`, `EndMQTransaction` |
| **Outcome** | The transactional queue always receives messages transactionally |
| **Source** | SAIF.Services.Printing/clsPrint.vb |

---

## BR-PRT-005 MSMQ failure rollback

| Field | Value |
| --- | --- |
| **Statement** | A failure while queueing a distribution rolls back the MSMQ transaction and rethrows. |
| **Trigger** | Exception in the asynchronous branch |
| **Enforcement** | `SAIF.Services.Printing/clsPrint.vb` — `Catch` in private `distributeDocument` |
| **Outcome** | No partially queued print request survives a failure |
| **Source** | SAIF.Services.Printing/clsPrint.vb |

---

## BR-PRT-006 Fixed paper tray for synchronous distribution

| Field | Value |
| --- | --- |
| **Statement** | Synchronous distribution always requests paper tray 2. |
| **Trigger** | Synchronous `distributeDocument` |
| **Enforcement** | `SAIF.Services.Printing/clsPrint.vb` — `PaperTray.Tray2` argument |
| **Outcome** | Direct distributions print from a fixed tray regardless of caller intent |
| **Source** | SAIF.Services.Printing/clsPrint.vb |

---

## BR-PRT-007 Render result caching

| Field | Value |
| --- | --- |
| **Statement** | A report is rendered only once unless the caller requests an overwrite. |
| **Trigger** | `ReportBase.Render` |
| **Enforcement** | `SAIF.Services.Printing/Reporting/ReportBase.vb` — `Render` |
| **Outcome** | Repeat calls reuse the cached `ReportFile` and avoid another xPression round trip |
| **Source** | SAIF.Services.Printing/Reporting/ReportBase.vb |

---

## BR-PRT-008 Render and distribute preconditions

| Field | Value |
| --- | --- |
| **Statement** | A report can be rendered or distributed only when its XML document exists and a report package is assigned. |
| **Trigger** | `ReportBase.Render`, `ReportBase.Distribute` |
| **Enforcement** | `SAIF.Services.Printing/Reporting/ReportBase.vb` |
| **Outcome** | Incomplete reports return `False` instead of calling xPression |
| **Source** | SAIF.Services.Printing/Reporting/ReportBase.vb |

---

## BR-PRT-009 Default printer and security platform selection

| Field | Value |
| --- | --- |
| **Statement** | The printer used for rendering is the current security principal's default printer, resolved for the Web platform when running in a web context (per `EnvironmentServiceBase.IsWeb`) and for Windows otherwise. |
| **Trigger** | `ReportBase.Render` |
| **Enforcement** | `SAIF.Services.Printing/Reporting/ReportBase.vb` — `Render` |
| **Outcome** | Output is targeted at the user's own default printer |
| **Source** | SAIF.Services.Printing/Reporting/ReportBase.vb |

---

## BR-PRT-010 Non-throwing render and distribute failures

| Field | Value |
| --- | --- |
| **Statement** | Render and distribute failures are recorded as `ErrorDetail` entries rather than thrown. |
| **Trigger** | Exception during `Render` or `Distribute` |
| **Enforcement** | `SAIF.Services.Printing/Reporting/ReportBase.vb` |
| **Outcome** | Callers inspect `Errors` and the operation returns `False` |
| **Source** | SAIF.Services.Printing/Reporting/ReportBase.vb |

---

## BR-PRT-011 Rendered file extension fixed by format

| Field | Value |
| --- | --- |
| **Statement** | The rendered file extension is fixed by the selected report format (CSV→csv, Excel→xls, HTML→html, Image→jpeg, PDF→pdf, Word→doc, XML→xml). |
| **Trigger** | Assignment to `clsRSPrint.Format` |
| **Enforcement** | `SAIF.Services.Printing/clsRSPrint.vb` — `Format` setter |
| **Outcome** | SSRS is asked for a format/extension pair that agree |
| **Source** | SAIF.Services.Printing/clsRSPrint.vb |

---

## BR-PRT-012 SSRS distribution not supported

| Field | Value |
| --- | --- |
| **Statement** | SSRS distribution is not supported. |
| **Trigger** | `clsRSPrint.DistributeDocument` |
| **Enforcement** | `SAIF.Services.Printing/clsRSPrint.vb` |
| **Outcome** | `NotImplementedException` is thrown |
| **Source** | SAIF.Services.Printing/clsRSPrint.vb |

---

## BR-PRT-013 Print and distribute report unconditional success

| Field | Value |
| --- | --- |
| **Statement** | The xPression print and distribute entry points always report success. |
| **Trigger** | `printPDF`, `distributeDocument` |
| **Enforcement** | `SAIF.Services.Printing/clsPrint.vb` |
| **Outcome** | Return value is `True` regardless of downstream outcome; failures surface only as exceptions |
| **Source** | SAIF.Services.Printing/clsPrint.vb |

---

## BR-PRT-014 Destination file overwrite protection

| Field | Value |
| --- | --- |
| **Statement** | An existing destination file is not replaced unless the caller requests an overwrite, and saving requires a destination file name. |
| **Trigger** | `ReportBase.Save` |
| **Enforcement** | `SAIF.Services.Printing/Reporting/ReportBase.vb` — `Save` |
| **Outcome** | Existing output files are protected from accidental replacement |
| **Source** | SAIF.Services.Printing/Reporting/ReportBase.vb |

---

## BR-PRT-015 Draft versus final output profile

| Field | Value |
| --- | --- |
| **Statement** | Draft output uses the `PDF_Draft_Watermark` profile and final output uses the `PDF` profile. |
| **Trigger** | `SetDraftProfile` / `SetDefaultProfile` |
| **Enforcement** | `SAIF.Services.Printing/Reporting/ReportBase.vb` |
| **Outcome** | Draft renderings carry a watermark |
| **Source** | SAIF.Services.Printing/Reporting/ReportBase.vb |

---

## BR-PRT-016 Key propagation for nested repeating sections

| Field | Value |
| --- | --- |
| **Statement** | Every primary key on an element, and every foreign key it inherited, is repeated as a foreign key on each descendant element that itself has children.* |
| **Trigger** | First (top-level) call to `ToXpression` |
| **Enforcement** | `SAIF.Services.Printing/Reporting/XDesignXElement.vb` — `PropagateKeys` |
| **Outcome** | xPression receives the key context it needs to associate nested repeating sections with their parents* |
| **Source** | SAIF.Services.Printing/Reporting/XDesignXElement.vb |

---

## BR-PRT-017 Empty-value self-closing elements

| Field | Value |
| --- | --- |
| **Statement** | An element with an empty value is emitted as a self-closing tag. |
| **Trigger** | `ToXpression` rendering of a leaf element |
| **Enforcement** | `SAIF.Services.Printing/Reporting/XDesignXElement.vb` — `RenderElement` |
| **Outcome** | Empty data points are represented without an empty text node |
| **Source** | SAIF.Services.Printing/Reporting/XDesignXElement.vb |

---

## BR-PRT-018 XML value escaping

| Field | Value |
| --- | --- |
| **Statement** | Element values are XML-escaped before emission. |
| **Trigger** | `ToXpression` rendering of a non-empty leaf |
| **Enforcement** | `SAIF.Services.Printing/Reporting/XDesignXElement.vb` — `RenderElement` |
| **Outcome** | Data containing markup characters cannot corrupt the xPression document |
| **Source** | SAIF.Services.Printing/Reporting/XDesignXElement.vb |

---

## BR-PRT-019 Empty serialization for malformed documents

| Field | Value |
| --- | --- |
| **Statement** | A document with no root, or whose root is not an xPression element, serializes to an empty string. |
| **Trigger** | `XDesignXDocument.ToXpression` |
| **Enforcement** | `SAIF.Services.Printing/Reporting/XDesignXDocument.vb` |
| **Outcome** | Malformed documents produce no xPression payload instead of an error |
| **Source** | SAIF.Services.Printing/Reporting/XDesignXDocument.vb |

---

## BR-PRT-020 SSRS execution under hosting process identity

| Field | Value |
| --- | --- |
| **Statement** | SSRS reports execute under the hosting process's default Windows credentials. |
| **Trigger** | `clsRSPrint.PreviewDocument` |
| **Enforcement** | `SAIF.Services.Printing/clsRSPrint.vb` |
| **Outcome** | Report-level data authorization is delegated to the SSRS server and the process identity |
| **Source** | SAIF.Services.Printing/clsRSPrint.vb |

## Notes

> **Note:** Statements marked with `*` were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with `**` could not be confirmed; treat as unknown until verified.

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Configuration](configuration.md)
- [API reference](api/index.md)

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `SAIF.Services.Printing/clsPrint.vb`
- `SAIF.Services.Printing/clsRSPrint.vb`
- `SAIF.Services.Printing/Reporting/IReport.vb`
- `SAIF.Services.Printing/Reporting/ReportBase.vb`
- `SAIF.Services.Printing/Reporting/XDesignXDocument.vb`
- `SAIF.Services.Printing/Reporting/XDesignXElement.vb`
- SAIF.Services.Printing/clsPrint.vb
- SAIF.Services.Printing/clsRSPrint.vb
- SAIF.Services.Printing/Reporting/ReportBase.vb
- SAIF.Services.Printing/Reporting/XDesignXDocument.vb
- SAIF.Services.Printing/Reporting/XDesignXElement.vb
